#include <stdio.h>
#include "sys_common.h"
#include "drvBoardinit.h"
#include "drvRTI.h"
#include "drvAdc.h"
#include "drvIO.h"
#include "drvTMP112.h"
#include "drvAt24c01.h"
#include "drvLTC4281.h"
#include "drvTCA9539.h"
#include "drvAd7616.h"
#include "drvTcan4550.h"

void TcTest_DI();
void TcTest_DO();
void TcTest_AX();

void appMain(void)
{
    char buf[64] = {0};
    BOARDID_T Boardid = {0};

    drvBoardInit();

    printf("[%10llu] [%s %d]:------------------------- appMainTask ------------------------------\r\n",
           rit_Getms(), __FUNCTION__, __LINE__);

    drvGetVersion(buf, (uint8_t)64);
    printf("[%10llu] [%s %d]: Date [%d-%d-%d] Ver:%s \r\n", rit_Getms(), __FUNCTION__, __LINE__,
           DRV_VER_YEAR, DRV_VER_MONTH, DEV_VER_DAY, buf);

    // read boardid
    drvReadBoardID(&Boardid);
    printf("[%10llu] [%s %d] typeid:0x%02x slotid:0x%02x\n\r", rit_Getms(), __FUNCTION__, __LINE__,
           Boardid.typeid, Boardid.slotid);

    switch (Boardid.typeid)
    {
        case BOARDTYPE_DI:
            TcTest_DI();
            break;

        case BOARDTYPE_DO:
            TcTest_DO();
            break;

        case BOARDTYPE_AX:
            TcTest_AX();
            break;

        default:
            break;
    }

    while(1)
    {
        rti_DelayMs(1000);
        printf("[%10llu] [%s %d]: running\r\n", rit_Getms(), __FUNCTION__, __LINE__);
    }
}

void TcTest_AX()
{
    int32_t ret = 0;
    uint32_t cnt = 0;
    uint32_t i = 0;
    uint32_t blocksize = AI_CHANNEL_COUNT;
    uint16_t buf[AI_CHANNEL_COUNT] = {0};
    CANFD_PARAM_T canfdParam[CANFD_CHN_MAX] = {0};

    uint8_t buf_canfd[64] = {0};
    CANFD_FRAME_T canfdFrame[CANFD_CHN_MAX] = {0};
    for (i = 0; i < 64; i++)
    {
        buf_canfd[i] = i;
    }

    TCAN4x5x_Reset(CANFD_CHN_1);
    TCAN4x5x_Reset(CANFD_CHN_2);
    TCAN4x5x_ReadID(CANFD_CHN_1);
    TCAN4x5x_ReadID(CANFD_CHN_2);



    canfdParam[CANFD_CHN_1].canfd_id = 0x100;
    canfdParam[CANFD_CHN_1].canfd_mask = 0x0000;
    drvTCAN4x5xInit(CANFD_CHN_1, &canfdParam[CANFD_CHN_1]);

    canfdParam[CANFD_CHN_2].canfd_id = 0x200;
    canfdParam[CANFD_CHN_2].canfd_mask = 0x0000;
    drvTCAN4x5xInit(CANFD_CHN_2, &canfdParam[CANFD_CHN_2]);


    while(1)
    {
        cnt++;
        rti_DelayMs(1000);
        printf("\r\n[%10llu] [%s %d]: running\r\n", rit_Getms(), __FUNCTION__, __LINE__);

        ret = drvAD7616GetSample(blocksize, buf);
        if (ret != 0)
        {
            printf("[%10llu] [%s %d]: drvAD7616GetSample err: %d\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            //vot = (*(INT16*)&code * ptr->cToVPara[i]) / 32.767;
            for (i = 0; i < AI_CHANNEL_COUNT; i++)
            {
                printf("[%10llu] [%s %d]: chn%02d 0x%04x ctov %f v\r\n",
                       rit_Getms(), __FUNCTION__, __LINE__, i, buf[i],
                       (*(int16_t*)&buf[i] * 10)/32.767);
            }
        }

        drvTCAN4x5xSendData(CANFD_CHN_1, buf_canfd, 64, 0x0101);
        drvTCAN4x5xSendData(CANFD_CHN_2, buf_canfd, 64, 0x0201);

        ret = drvTCAN4x5xRecvData(CANFD_CHN_1, &canfdFrame[CANFD_CHN_1]);
        if (ret == 0)
        {
            printf("[%10llu] [%s %d]: canfd1 id 0x%04x datalen %d\r\n", rit_Getms(), __FUNCTION__, __LINE__,
                   canfdFrame[CANFD_CHN_1].canfd_id, canfdFrame[CANFD_CHN_1].data_len);
            printf("[%10llu] [%s %d]: data: ", rit_Getms(), __FUNCTION__, __LINE__);
            for (i = 0; i < canfdFrame[CANFD_CHN_1].data_len; i++)
            {
                printf("0x%02x ", canfdFrame[CANFD_CHN_1].data[i]);
            }
            printf("\n\r");
        }
        else
        {
            printf("[%10llu] [%s %d]: ret %d\n\r", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

        ret = drvTCAN4x5xRecvData(CANFD_CHN_2, &canfdFrame[CANFD_CHN_2]);
        if (ret == 0)
        {
            printf("[%10llu] [%s %d]: canfd2 id 0x%04x datalen %d\r\n", rit_Getms(), __FUNCTION__, __LINE__,
                   canfdFrame[CANFD_CHN_2].canfd_id, canfdFrame[CANFD_CHN_2].data_len);
            printf("[%10llu] [%s %d]: data: ", rit_Getms(), __FUNCTION__, __LINE__);
            for (i = 0; i < canfdFrame[CANFD_CHN_2].data_len; i++)
            {
                printf("0x%02x ", canfdFrame[CANFD_CHN_2].data[i]);
            }
            printf("\n\r");
        }
        else
        {
            printf("[%10llu] [%s %d]: ret %d\n\r", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
    }

}

void TcTest_DI()
{
    int32_t ret = 0;
    uint32_t i = 0;
    uint32_t cnt = 0;
    float Temp = 0;
    uint8_t buf[2][8] = {0};
    struct HotSwapPara hotswap;

    uint32_t value_di = 0;

    drvTMP112Init((int16_t)10000, (int16_t)-4000);

    hotswap.voltage = v24;
    drvHotSwapInit(&hotswap);

    while(1)
    {
        cnt++;
        rti_DelayMs(1000);
        printf("\r\n[%10llu] [%s %d]: running\r\n", rit_Getms(), __FUNCTION__, __LINE__);

        // TMP112 test
        ret = drvTMP112ReadTemp(&Temp);
        if (ret == 0)
        {
            printf("[%10llu] [%s %d]: Temp %f\r\n", rit_Getms(), __FUNCTION__, __LINE__, Temp);
        }

        ret = drvTMP112CheckState();
        if (ret == TEMP_EXCEED)
        {
            printf("[%10llu] [%s %d]: Temp TEMP_EXCEED!\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }

        // at24c01 test
        for (i = 0; i < 8; i++)
        {
            buf[0][i] = i;
        }
        drvWriteEEPROM(0, buf[0], 8);
        drvReadEEPROM(0, buf[1], 8);
        //printf("[%10llu] [%s %d]: ReadEEPROM: ", rit_Getms(), __FUNCTION__, __LINE__);
        for (i = 0; i < 8; i++)
        {
            //printf("%d ", buf[1][i]);
            if (buf[1][i] != buf[0][i])
            {
                break;
            }
        }

        printf("\n\r");

        if (i == 8)
        {
            printf("[%10llu] [%s %d]: EEPROM test success\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }
        else
        {
            printf("[%10llu] [%s %d]: EEPROM test failure\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }

        // swap test
        ret = drvReadVoltage(LTC4281_PRE_VALUE);
        if (ret > 26400)
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d highAlarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else if (ret < 21600)
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d lowAlarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d success\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

        ret = drvReadCurrent(LTC4281_PRE_VALUE);
        if (ret > 400)
        {
            printf("[%10llu] [%s %d]: LTC4281.curr %d Alarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            printf("[%10llu] [%s %d]: LTC4281.curr %d success\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

        // EarthDetect
        ret = drvEarthDetect_DI();
        if (ret == 0)
        {
            printf("[%10llu] [%s %d]: drvEarthDetect_DI %d success\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            printf("[%10llu] [%s %d]: drvEarthDetect_DI %d failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

        // DI test

        drvIOSet_DIAGDRV_DI(1);

        drvIOGet_DIAG_DI(&value_di);
        printf("[%10llu] [%s %d]: Get DI diag_input: %d\r\n", rit_Getms(), __FUNCTION__, __LINE__, value_di);

#if 1
        for (i = 0; i < DI_DRVC_LEN; i++)
        {
            drvIOSet_DRV_DI(i, 1);
        }
#endif


        printf("[%10llu] [%s %d]: Get DI input:\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        for (i = 0; i < DI_CHANNLE_LEN; i++)
        {
            ret = drvIOGet_DI(i, &value_di);
            printf("[%d]%d ", i, value_di);
        }
        printf("\r\n");


    }
}

void TcTest_DO()
{
    int32_t ret = 0;
    uint32_t i = 0;
    uint8_t dofb = 0;
    uint32_t cnt = 0;
    float Temp = 0;
    uint8_t buf[2][8] = {0};
    struct HotSwapPara hotswap;

    drvTMP112Init((int16_t)10000, (int16_t)-4000);

    hotswap.voltage = v24;
    drvHotSwapInit(&hotswap);


    while(1)
    {
        cnt++;
        rti_DelayMs(1000);
        printf("\r\n[%10llu] [%s %d]: running\r\n", rit_Getms(), __FUNCTION__, __LINE__);

        // TMP112 test
        ret = drvTMP112ReadTemp(&Temp);
        if (ret == 0)
        {
            printf("[%10llu] [%s %d]: Temp %f\r\n", rit_Getms(), __FUNCTION__, __LINE__, Temp);
        }

        ret = drvTMP112CheckState();
        if (ret == TEMP_EXCEED)
        {
            printf("[%10llu] [%s %d]: Temp TEMP_EXCEED!\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }

        // at24c01 test
        for (i = 0; i < 8; i++)
        {
            buf[0][i] = i;
        }
        drvWriteEEPROM(0, buf[0], 8);
        drvReadEEPROM(0, buf[1], 8);
        //printf("[%10llu] [%s %d]: ReadEEPROM: ", rit_Getms(), __FUNCTION__, __LINE__);
        for (i = 0; i < 8; i++)
        {
            //printf("%d ", buf[1][i]);
            if (buf[1][i] != buf[0][i])
            {
                break;
            }
        }

        printf("\n\r");

        if (i == 8)
        {
            printf("[%10llu] [%s %d]: EEPROM test success\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }
        else
        {
            printf("[%10llu] [%s %d]: EEPROM test failure\r\n", rit_Getms(), __FUNCTION__, __LINE__);
        }

        // swap test
        ret = drvReadVoltage(LTC4281_PRE_VALUE);
        if (ret > 26400)
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d highAlarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else if (ret < 21600)
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d lowAlarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            printf("[%10llu] [%s %d]: LTC4281.volt %d success\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

        ret = drvReadCurrent(LTC4281_PRE_VALUE);
        if (ret > 400)
        {
            printf("[%10llu] [%s %d]: LTC4281.curr %d Alarm failure!\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }
        else
        {
            printf("[%10llu] [%s %d]: LTC4281.curr %d success\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }


        // DOFB test
        if ((cnt % 2) == 0)
        {
            for (i = 0; i < DO_CHANNLE_LEN; i++)
            {
                drvIOSet_DO(i, 0);
            }
        }
        else
        {
            for (i = 0; i < DO_CHANNLE_LEN; i++)
            {
                drvIOSet_DO(i, 1);
            }
        }


        ret = drvADCRefresh();
        if (ret == 0)
        {
            for (i = 0; i < ADC_CHANNEL_CNT; i++)
            {
                dofb = drvADCGet(i);
                printf("[%10llu] [%s %d]: chanl[%02d] dofb %d\r\n", rit_Getms(), __FUNCTION__, __LINE__, (i+1), dofb);
            }
        }
        else
        {
            printf("[%10llu] [%s %d]: drvADCRefresh err ret=%d\r\n", rit_Getms(), __FUNCTION__, __LINE__, ret);
        }

    }
}




